<template>
    <div v-click-outside class="select" :style="{ width: width }">
        <div class="input-field" :style="{ 'color': selectedOption.label ? '#292E3D' : 'rgba(41, 46, 61, 0.5)' }"
            @click="toggleDropdown">
            <span class="text">{{ showSelectTxt() }}</span>
            <div class="suffix" :class="[showDropdown ? 'arrow-btn__toggle' : '']" @click.stop="clickArrow">
                <el-icon v-if="!showDropdown" :class="arrowClass">
                    <ArrowDown />
                </el-icon>
                <el-icon v-else :class="arrowClass">
                    <ArrowUp />
                </el-icon>
                <el-icon class="clear" :class="clearClass">
                    <CircleClose />
                </el-icon>
            </div>
        </div>
        <div v-if="showDropdown" class="dropdown">
            <div v-for="(option, index) in options" :key="index" @click="select(option)"
                :class="{ 'selected': selectedOption[valueKey] == option[valueKey] }">
                {{ option.label }}
            </div>
        </div>
    </div>
</template>

<script setup>
import { watch, ref, onMounted, computed } from 'vue'
import { ArrowUp, ArrowDown, CircleClose } from '@element-plus/icons-vue'

const emit = defineEmits(['click', 'change']);
const model = defineModel({ required: true })
const props = defineProps({
    defaultSelectIndex: {
        type: Number,
    },
        tip: {
            type: String,
            default: ''
        },
    options: {
        type: Array,
        required: true
    },
    prefixText: {
        type: String,
        default: ''
    },
    placeholder: {
        type: String,
        default: '请选择'
    },
    width: {
        type: String,
        default: ''
    },
    valueKey: {
        type: String,
        default: 'value'
    },
    clearable: Boolean,
})

const selectedOption = ref({})
const showDropdown = ref(false)

watch(() => model, (newValue) => {
    setSelected(newValue)
});

const showSelectTxt = () => {
    if (!selectedOption.value.label) {
        return props.placeholder
    }
    return props.prefixText
        ? props.prefixText + '：' + selectedOption.value.label
        : selectedOption.value.label
}
const arrowClass = computed(() => {
    return selectedOption.value.label && props.clearable ? 'hide' : ''
})
const clearClass = computed(() => {
    return selectedOption.value.label && props.clearable ? 'show' : ''
})

const toggleDropdown = () => {
    showDropdown.value = !showDropdown.value
}
const clickArrow = () => {
    if (props.clearable && selectedOption.value.label) {
        deleteSelected()
    } else {
        showDropdown.value = !showDropdown.value
    }
}
const select = (option) => {
    selectedOption.value = option
    showDropdown.value = false
    model.value = option[props.valueKey]

    if (model.value !== option[props.valueKey]) {
        emit('change', option[props.valueKey]);
    }
}
const setSelected = (val) => {
    if (props.options?.length > 0) {
        const option = props.options.find(item => item[props.valueKey] == val)
        selectedOption.value = option ? option : {}
        showDropdown.value = false
    }
}
const deleteSelected = () => {
    selectedOption.value = {}
    showDropdown.value = false
    model.value = null
    emit('change', {});
}
const reset = () => {
    if (props.defaultSelectIndex > -1) {
        selectedOption.value = props.options[props.defaultSelectIndex]
    }
    showDropdown.value = false
}

const vClickOutside = {
    mounted(el, binding) {
        function eventHandler(e) {
            if (!el.contains(e.target)) {
                showDropdown.value = false
            }
        }
        // 用于销毁前注销事件监听
        el.__click_outside__ = eventHandler
        // 添加事件监听
        document.addEventListener('click', eventHandler)
    },
    beforeUnmount(el) {
        // 移除事件监听
        document.removeEventListener('click', el.__click_outside__)
        // 删除无用属性
        delete el.__click_outside__
    }
}

onMounted(() => {
    reset()
})

</script>

<style lang="less" scoped>
.select {
    position: relative;
    display: inline-block;
    height: 48px;
    width: 200px;
    border-radius: 50%;

    .input-field {
        height: 100%;
        // width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-between;
        cursor: pointer;
        border-radius: 50px;
        color: #24223480;
        background: #24223408;
        outline: none;
        font-size: 14px;
        border: 1px solid rgba(41, 46, 61, 0.1);
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;

        &:hover {
            .hide {
                display: none;
            }

            .show {
                display: inline-block;
            }
        }

        .text {
            display: inline-block;
            width: 100%;
            padding-left: 15px;
            overflow: hidden;
            text-overflow: ellipsis;
        }
    }

    .suffix {
        display: flex;
        cursor: pointer;
        text-align: center;
        color: #132241;
        background-color: #24223408;
        width: 48px;
        height: 48px;
        justify-content: center;
        align-items: center;
        border-radius: 50px;
        flex-shrink: 0;
        box-sizing: border-box;
        .clear {
            font-size: 12px;
            display: none;
        }
    }

    .dropdown {
        position: absolute;
        background-color: white;
        box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
        z-index: 9999;
        top: 52px;
        min-width: 100%;
        width: auto;
        white-space: nowrap;
        border-radius: 16px;
        padding: 8px;
        font-size: 14px;
        user-select: none;

        .selected {
            color: #409EFF;
            font-weight: 700;
        }
    }

    .dropdown div {
        padding: 14px;
        cursor: pointer;
        border-radius: 16px;
    }

    .dropdown div:hover {
        background-color: #F5F7FA;
    }
}
</style>
